package it.abc.sicsic;

import it.abc.sicsic.model.barche.Barche;
import it.abc.sicsic.model.clienti.Clienti;
import it.abc.sicsic.model.skipper.Skipper;

import it.abc.sicsic.model.spese.Spese;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import javax.persistence.Query;

public class JavaServiceFacade {
    private static final boolean isAutoCommit = true;
    private final EntityManagerHelper entityManagerHelper;

    public JavaServiceFacade() {
        entityManagerHelper = new EntityManagerHelper("sicsic-model-1", isAutoCommit);
    }

    public Object queryByRange(String jpqlStmt, int firstResult, int maxResults) {
        Query query = entityManagerHelper.getEntityManager().createQuery(jpqlStmt);
        if (firstResult > 0) {
            query = query.setFirstResult(firstResult);
        }
        if (maxResults > 0) {
            query = query.setMaxResults(maxResults);
        }
        return query.getResultList();
    }


    /** <code>select o from Skipper o</code> */
    public List<Skipper> getSkipperFindAll() {
        return entityManagerHelper.getEntityManager().createNamedQuery("Skipper.findAll").getResultList();
    }
    
    /** select SKIPPER */
    public List<Skipper> getSkipper(String nomeSkipper, String residenza){
        String nS = isNullOrEmpty(nomeSkipper) ? null : nomeSkipper.concat("%");
        String rS = isNullOrEmpty(residenza) ? null : residenza.concat("%"); 
        Query q = entityManagerHelper.getEntityManager().createNativeQuery(Skipper.FIND_BARCHE, Skipper.class);
        q.setParameter(1, nS)
            .setParameter(2, nS)
            .setParameter(3, rS)
            .setParameter(4, rS);
        return q.getResultList();        
    }

    public Skipper persistSkipper(Skipper skipper) {
        return (Skipper)entityManagerHelper.persistEntity(skipper);
    }

    public Skipper mergeSkipper(Skipper skipper) {
        return (Skipper)entityManagerHelper.mergeEntity(skipper);
    }

    public void removeSkipper(Skipper skipper) {
        skipper = entityManagerHelper.getEntityManager().find(Skipper.class, skipper.getId());
        entityManagerHelper.removeEntity(skipper);
    }

    /** <code>select o from Clienti o</code> */
    public List<Clienti> getClientiFindAll() {
        return entityManagerHelper.getEntityManager().createNamedQuery("Clienti.findAll").getResultList();
    }
    
    public Clienti persistClienti(Clienti clienti) {
        return (Clienti)entityManagerHelper.persistEntity(clienti);
    }

    public Clienti mergeClienti(Clienti clienti) {
        return (Clienti)entityManagerHelper.mergeEntity(clienti);
    }

    public void removeClienti(Clienti clienti) {
        clienti = entityManagerHelper.getEntityManager().find(Clienti.class, clienti.getId());
        entityManagerHelper.removeEntity(clienti);
    }
    
    /** select CLIENTI */
    public List<Clienti> getClienti( String nome,
                                     String cognome,
                                     String ragioneSociale,
                                     String citta,
                                     String documento,
                                     String telefono) {
      
        String n = isNullOrEmpty(nome) ? null : nome.concat("%");
        String s = isNullOrEmpty(cognome)  ?  null : cognome.concat("%");        
        String r = isNullOrEmpty(ragioneSociale) ? null : ragioneSociale.concat("%");
        String c = isNullOrEmpty(citta)  ?  null : citta.concat("%"); 
        String d = isNullOrEmpty(documento) ? null : documento.concat("%");
        String t = isNullOrEmpty(telefono) ? null : telefono.concat("%");

        Query q = entityManagerHelper.getEntityManager()
                .createNativeQuery(Clienti.FIND_CLIENTI, Clienti.class); 
        q.setParameter(1, n)
            .setParameter(2, n)
            .setParameter(3, s)
            .setParameter(4, s)
        .setParameter(5, r)
        .setParameter(6, r)
        .setParameter(7, c)
        .setParameter(8, c)
        .setParameter(9, d)
        .setParameter(10, d)
        .setParameter(11, t)
        .setParameter(12, t);
        return q.getResultList();    
    }
    
    /** <code>select o from Barche o</code> */
    public List<Barche> getBarcheFindAll() {
        return entityManagerHelper.getEntityManager().createNamedQuery("Barche.findAll").getResultList();
    }

    /** select BARCHE */
    public List<Barche> getBarche(String nomeBarca, String modello){
        String nB = isNullOrEmpty(nomeBarca) ? null : nomeBarca.concat("%");
        String mB = isNullOrEmpty(modello) ? null : modello.concat("%"); 
        Query q = entityManagerHelper.getEntityManager().createNativeQuery(Barche.FIND_BARCHE, Barche.class);
        q.setParameter(1, nB)
            .setParameter(2, nB)
            .setParameter(3, mB)
            .setParameter(4, mB);
        return q.getResultList();        
    }
    
    public Barche persistBarche(Barche barche) {
        return (Barche)entityManagerHelper.persistEntity(barche);
    }

    public Barche mergeBarche(Barche barche) {
        return (Barche)entityManagerHelper.mergeEntity(barche);
    }

    public void removeBarche(Barche barche) {
        barche = entityManagerHelper.getEntityManager().find(Barche.class, barche.getId());
        entityManagerHelper.removeEntity(barche);
    }
    
    /** <code>select o from Spese o</code> */
    public List<Spese> getSpeseFindAll() {
        return entityManagerHelper.getEntityManager().createNamedQuery("Spese.findAll").getResultList();
    }
    
    /** <code>select o from Spese o</code> */
    public List<Spese> getSpeseFindAllMonth() {
        return entityManagerHelper.getEntityManager().createNativeQuery(Spese.FIND_SPESE_PER_MESE, Spese.class).getResultList();
    }
   
    /** select SPESE */
    public List<Spese> getSpese(String data, String barca){
        String dS = isNullOrEmpty(data) ? null : data.concat("%");
        String bS = isNullOrEmpty(barca) ? null : barca.concat("%"); 
        Query q = entityManagerHelper.getEntityManager().createNativeQuery(Spese.FIND_SPESE, Spese.class);
        q.setParameter(1, dS)
            .setParameter(2, dS)
            .setParameter(3, bS)
            .setParameter(4, bS);
        return q.getResultList();        
    }
    
    public Spese persistSpese(Spese spese) {
        return (Spese)entityManagerHelper.persistEntity(spese);
    }
   
    public Spese mergeSpese(Spese spese) {
        return (Spese)entityManagerHelper.mergeEntity(spese);
    }

    private boolean isNullOrEmpty(String s){
        return s == null || s.isEmpty();
    }


    private class EntityManagerHelper {
        final private EntityManagerFactory _entityManagerFactory;
        final private boolean _isAutoCommit;

        private EntityManager _entityManager;

        EntityManagerHelper(String persistenceUnit, boolean isAutoCommit) {
            _entityManagerFactory = Persistence.createEntityManagerFactory(persistenceUnit);
            _isAutoCommit = isAutoCommit;
        }

        public EntityManager getEntityManager() {
            if (_entityManager == null) {
                _entityManager = _entityManagerFactory.createEntityManager();
            }

            return _entityManager;
        }

        public EntityTransaction getEntityTransaction() {
            return getEntityManager().getTransaction();
        }

        public void commitTransaction() {
            final EntityTransaction entityTransaction = getEntityTransaction();
            if (entityTransaction.isActive()) {
                entityTransaction.commit();
            }

            _closeEntityManager();
        }

        public void rollbackTransaction() {
            final EntityTransaction entityTransaction = getEntityTransaction();
            if (entityTransaction.isActive()) {
                entityTransaction.rollback();
            }

            _closeEntityManager();
        }

        public boolean isTransactionDirty() {
            return (!_isAutoCommit && getEntityTransaction().isActive());
        }

        public Object persistEntity(Object entity) {
            _beginTransactionIfNeeded();
            _entityManager.persist(entity);
            _commitTransactionIfNeeded();

            return entity;
        }

        public Object mergeEntity(Object entity) {
            _beginTransactionIfNeeded();
            entity = _entityManager.merge(entity);
            _commitTransactionIfNeeded();

            return entity;
        }

        public void removeEntity(Object entity) {
            _beginTransactionIfNeeded();
            _entityManager.remove(entity);
            _commitTransactionIfNeeded();
        }

        private void _beginTransactionIfNeeded() {
            final EntityTransaction entityTransaction = getEntityTransaction();
            if (!entityTransaction.isActive()) {
                entityTransaction.begin();
            }
        }

        private void _commitTransactionIfNeeded() {
            if (_isAutoCommit) {
                commitTransaction();
            }
        }

        private void _closeEntityManager() {
            if (_entityManager != null && _entityManager.isOpen()) {
                _entityManager.close();
            }

            _entityManager = null;
        }
    }
}
